package com.cloudRestudy.hystrix.service.impl;

import cn.hutool.core.util.IdUtil;
import com.cloudRestudy.common.core.result.R;
import com.cloudRestudy.hystrix.service.HystrixService;
import com.mysql.cj.util.TimeUtil;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName : HystrixServiceImpl
 * @Author : lby
 * @Date: 2021/7/21 17:52
 * @Description :
 * 全局默认降级方法   DefaultProperties
 * @HystrixCommand(fallbackMethod = "fallBackMsg",commandProperties = {
 * @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS,value = "1000")
 * })
 * 需要单独配置
 */
@Service
public class HystrixServiceImpl implements HystrixService {
    @Override
    @HystrixCommand
    public R successMsg() {
        R r = new R();
        String data = "当前线程是" + Thread.currentThread().getName() + "成功的操作";
        r.setData(data);
        return r;
    }

    @Override
    @HystrixCommand(fallbackMethod = "fallBackMsg", commandProperties = {
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "1000")
    })
    public R errorMsg() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        R r = new R();
        String data = "当前线程是" + Thread.currentThread().getName() + "失败的操作";
        r.setData(data);
        return r;
    }

    public R fallBackMsg() {
        return R.failed("服务超时Le");
    }


    /**
     * 全局降级方法
     * 如果接口需要参数，这里也要写入参数
     * @return
     */
    public R globalFallback(Integer randomId) {
        return R.failed(randomId,"不能为0或负数");
    }


    /**
     * 服务熔断
     * 断路器开启条件
     * @return
     */
    @Override
    @HystrixCommand(fallbackMethod = "globalFallback", commandProperties = {
            // 是否开启断路器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED, value = "true"),
            // 允许请求次数
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10"),
            // 允许请求时间范围
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "10000"),
            // 失败率范围，超过执行断路器
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50")


    })
    public R circuitBreakerTest(Integer randomId) throws Exception {
        if (randomId <= 0) {
            // 这里需要抛出异常，否则无法触发断路器
            throw new Exception("不能为0或负数");
        }
        String s = IdUtil.randomUUID();
        return R.ok(Thread.currentThread().getName() + "   " + s, "调用成功");
    }
}
